package com.tcxhb.job.dao.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tcxhb.job.dao.dataobject.JobInfoDO;
import com.tcxhb.job.dao.dataobject.query.JobInfoQuery;
import com.tcxhb.job.dao.dataobject.query.JobScanQuery;
import com.tcxhb.job.dao.mapper.JobInfoMapper;
import com.tcxhb.job.dao.repository.JobInfoRepository;
import com.tcxhb.job.common.constants.enums.JobStatusEnum;
import com.tcxhb.job.common.constants.enums.ScheduleTypeEnum;
import com.tcxhb.job.common.model.PageResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * author:auto.generator
 * time: 2023-11-02
 */
@Repository
public class JobInfoRepositoryImpl extends ServiceImpl<JobInfoMapper, JobInfoDO> implements JobInfoRepository {

    @Override
    public Long create(JobInfoDO jobInfoDO) {
        super.save(jobInfoDO);
        return jobInfoDO.getId();
    }

    @Override
    public boolean deleteById(Long id) {
        return super.removeById(id);
    }

    @Override
    public boolean updateById(JobInfoDO jobInfoDO) {
        return super.updateById(jobInfoDO);
    }

    @Override
    public JobInfoDO queryById(Long id) {
        return super.getById(id);
    }

    @Override
    public PageResponse<JobInfoDO> page(JobInfoQuery query) {
        LambdaQueryWrapper<JobInfoDO> wrapper = queryWrapper(query);
        Page<JobInfoDO> page = new Page<>(query.getPage().getPageNum(), query.getPage().getPageSize());
        IPage response = page(page, wrapper);
        PageResponse result = new PageResponse();
        result.setTotal(response.getTotal());
        result.setList(response.getRecords());
        return result;
    }

    @Override
    public List<JobInfoDO> list(JobInfoQuery query) {
        LambdaQueryWrapper<JobInfoDO> wrapper = queryWrapper(query);
        return super.list(wrapper);
    }

    @Override
    public List<JobInfoDO> scan(JobScanQuery query) {
        LambdaQueryWrapper<JobInfoDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.gt(query.getLastId() != null, JobInfoDO::getId, query.getLastId());
        //开始时间必填
        wrapper.le(JobInfoDO::getNextTime, query.getStartTime());
        wrapper.eq(JobInfoDO::getStatus, JobStatusEnum.start.getType());
        wrapper.eq(JobInfoDO::getScheduleType, ScheduleTypeEnum.Cron.getType());
        wrapper.last(" limit " + query.getLimit());
        wrapper.select(
                JobInfoDO::getId,
                JobInfoDO::getNextTime,
                JobInfoDO::getLastTime,
                JobInfoDO::getScheduleType,
                JobInfoDO::getScheduleConf
        );
        return super.list(wrapper);
    }

    @Override
    public boolean freshNextTime(JobInfoDO update) {
        LambdaUpdateWrapper<JobInfoDO> wrapper = Wrappers.<JobInfoDO>lambdaUpdate();
        wrapper.eq(JobInfoDO::getId, update.getId());
        wrapper.eq(JobInfoDO::getNextTime, update.getLastTime());
        wrapper.set(JobInfoDO::getNextTime, update.getNextTime());
        wrapper.set(JobInfoDO::getLastTime, update.getLastTime());
        return super.update(update, wrapper);
    }

    private LambdaQueryWrapper<JobInfoDO> queryWrapper(JobInfoQuery query) {
        LambdaQueryWrapper<JobInfoDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(query.getId() != null, JobInfoDO::getId, query.getId());
        if (!CollectionUtils.isEmpty(query.getIds())) {
            wrapper.in(JobInfoDO::getId, query.getIds());
        }
        if (query.getScheduleType() != null) {
            wrapper.eq(JobInfoDO::getScheduleType, query.getScheduleType());
        }
        if (StringUtils.isNotBlank(query.getJobName())) {
            wrapper.like(JobInfoDO::getJobName, query.getJobName());
        }
        if (query.getStatus() != null) {
            wrapper.eq(JobInfoDO::getStatus, query.getStatus());
        }
        if (StringUtils.isNotBlank(query.getAppName())) {
            wrapper.like(JobInfoDO::getAppName, query.getAppName());
        }
        return wrapper;
    }
}
